import { _toast } from "../utils"
class Validator{
  constructor(caches = []){
    this.cache = [...caches]
    this._getRules()
  }
  _getRules(){
    const query = wx.createSelectorQuery();
    query.selectAll(".rui-validate").fields({
      id: true,
      dataset: true,
      properties: ['validate', 'fieldtitle'],
      context: true
    }, res => {
      res.dataset,        
      res.context
    }).exec(res => {
      const rules = res[0];  
      rules.forEach(this.addRule.bind(this))          
    })
  }
  addRule(rule){
    let { dataset } = rule
    let { validate, vtype, fieldtitle, order } = dataset
    let vnames = validate.split("|")
    let orders = order.split("|")
    vnames.forEach((name,index) => {
      this.cache.push({
        order: orders[index],
        rule: name,
        msg: fieldtitle,
        vtype
      })
    })
  }
  add(opts){
    let type = Object.prototype.toString.call(opts)
    if (type === '[object Array]'){
      this.cache = [...this.cache, ...opts]
    } else if(type === '[object Object]'){
      this.cache = [...this.cache, opts]
    }
    return this
  }
  // 验证规则方法
  ruleMethods(method, val){
    let boolObj = {
      boolf: value => (value === false),
      boolt: value => (value === true),
      noEmpty: value => {
        return value == "" || value == undefined || value == null || value == "null"
      },
      phone: value => (!/^1[3-9]\d{9}$/.test(value)),
      url: value => (!/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value)),
      tel: value => (!/^[0-9]{3,4}(\-)?[0-9]{6,8}(\-)?([0-9]{1,4})$/.test(value)),
      email: value => (!/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value)),
      date: value => (!/Invalid|NaN/.test(new Date(value).toString())),
      dateIOS: value => (!/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)),
      number: value => (!/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)),
      int: value => (!/^\d+$/.test(value)),

    }
    if(method && boolObj[method]){
      return boolObj[method](val)
    } else {
      _toast(method + ' 验证方法不存在！')
      return true
    }
  }
  // 验证规则提示
  ruleName(method = 'boolf'){
    let val = {
      boolf: '',
      boolt: '',
      noEmpty: '不能为空！',
      phone: '格式不正确！',
      url: '格式不正确！',
      tel: '格式不正确！',
      email: '格式不正确！',
      date: '格式不正确！',
      dateIOS: '格式不正确！',
      number: '格式不正确！',
      int: '格式不正确！',
    }[method]
    return val ? val : ''
  }
  check(from = {}){
    let caches = JSON.stringify(this.cache)
    this.cache.forEach((item,index) => {
      if(item.order == 0){}else if(!item.order){
        item.order = index
      }
      let type = item.vtype
      let rule = item.rule
      item.rule = this.ruleMethods(rule, from[type])
      item.msg = `${item.msg}${this.ruleName(rule)}`
    })
    // 排序
    this.cache.sort((a,b) => a.order - b.order)
    let bool = this.start()
    this.cache = JSON.parse(caches)
    return bool
  }
  start(){
    for(let i = 0, validatorObj; validatorObj = this.cache[i++];){
      if(validatorObj.rule){
        _toast(validatorObj.msg)
        return false
      }
    }
    return true
  }
}

module.exports = Validator